package cn.py.boot_lua.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/***
  * @Message 线程池创建配置类
  * Author liangxs
 * @Date 2024-12-11
 */

@Slf4j
@Configuration
@EnableAsync
public class AsyncPoolConfig implements AsyncConfigurer {

    // 线程计数器
    private static final AtomicInteger THREAD_COUNT = new AtomicInteger(1);

    /***
     *  默认线程池配置
     * @return
     */
    @Bean(name = "defaultThreadPoolTaskExecutor")
    public ThreadPoolTaskExecutor defaultThreadPoolTaskExecutor() {
        ThreadPoolTaskExecutor executor = createThreadPoolTaskExecutor("DefaultThreadPool-", 5, 16, 50, 60);
        return executor;
    }


    /***
     * 任务线程池
     * @return
     */
    @Bean(name = "taskExecutor")
    public ThreadPoolTaskExecutor taskExecutor(){
        ThreadPoolTaskExecutor executor = createThreadPoolTaskExecutor("taskExecutor-", 5, 16, 50, 60);
        return executor;
    }


    /***
     * 虚拟线程池
     */
    @Bean(name = "virtualThreadPoolTaskExecutor")
    public Executor ttsThreadPoolTaskExecutor() {
        Executor executor = newVirtualExecutor("virtualThreadPoolTaskExecutor-");
        log.info("虚拟线程池 virtualThreadPoolTaskExecutor 创建成功");
        return executor;
    }


    /***
     * 定时任务线程池
      * @return
     */
    @Bean("scheduledExecutor")
    public ScheduledExecutorService scheduledExecutor() {
        // 核心线程数
        int corePoolSize = 6;
        // 自定义线程工厂
        ThreadFactory threadFactory = r -> {
            Thread t = new Thread(r, "scheduled-pool-thread-" + THREAD_COUNT.getAndIncrement());
            t.setDaemon(false);   // 非守护线程，防止JVM 提前退出
            t.setPriority(Thread.NORM_PRIORITY); // 标准优先级
            return t;
        };

        // 防止任务提交失败直接抛异常
        ScheduledThreadPoolExecutor executor = getScheduledThreadPoolExecutor(corePoolSize, threadFactory);
        return executor;
    }

    private static ScheduledThreadPoolExecutor getScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory) {
        RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();
        // 手动创建 ScheduledThreadPoolExecutor
        ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(
                corePoolSize,
                threadFactory,
                handler
        );

        executor.setRemoveOnCancelPolicy(true); // 取消任务后自动从队列移除，防止内存泄漏
        executor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);   // shutdown 后不执行延迟任务
        executor.setContinueExistingPeriodicTasksAfterShutdownPolicy(false); // shutdown 后不继续周期任务
        return executor;
    }


    /***
     * 创建线程池
     * @param threadNamePrefix 线程名称前缀
     * @param corePoolSize  核心线程数
     * @param maxPoolSize  最大线程数
     * @param queueCapacity  任务队列容量
     * @param keepAliveSeconds 非核心线程空闲存活时间
     * @return
     */
    private ThreadPoolTaskExecutor createThreadPoolTaskExecutor(String threadNamePrefix, int corePoolSize, int maxPoolSize, int queueCapacity, int keepAliveSeconds) {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.setKeepAliveSeconds(keepAliveSeconds);
        executor.setThreadNamePrefix(threadNamePrefix);
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());

        //自定义线程工厂
        executor.setThreadFactory(r -> {
            Thread t = new Thread(r, threadNamePrefix + "-" + Thread.currentThread().getId());
            t.setDaemon(true);
            return t;
        });

        executor.initialize();
        return executor;
    }


    /**
     * 创建虚拟线程池
     */
    private Executor newVirtualExecutor(String namePrefix) {
        ThreadFactory factory = Thread.ofVirtual().name(namePrefix, 0).factory();
        return Executors.newThreadPerTaskExecutor(factory);
    }


    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new AsyncError();
    }

}




